package com.dxx.cloud.admin.service.impl;

import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dxx.cloud.admin.mapper.GoodsSizeMapper;
import com.dxx.cloud.admin.module.entity.CustomerCart;
import com.dxx.cloud.admin.module.entity.CustomerEntity;
import com.dxx.cloud.admin.module.entity.GoodsEntity;
import com.dxx.cloud.admin.module.entity.GoodsSizeEntity;
import com.dxx.cloud.admin.module.request.GoodsSizeAddRequest;
import com.dxx.cloud.admin.module.request.GoodsSizeListRequest;
import com.dxx.cloud.admin.module.response.CustomerCartResponse;
import com.dxx.cloud.admin.module.response.GoodsResponse;
import com.dxx.cloud.admin.module.response.GoodsSizeResponse;
import com.dxx.cloud.admin.service.ICustomerCartService;
import com.dxx.cloud.admin.service.ICustomerService;
import com.dxx.cloud.admin.service.IGoodsService;
import com.dxx.cloud.admin.service.IGoodsSizeService;
import com.dxx.cloud.admin.utils.EntityUtils;
import jakarta.annotation.Resource;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品规格 服务实现类
 * </p>
 *
 * @author dh
 * @since 2025-06-06
 */
@Service
public class GoodsSizeServiceImpl extends ServiceImpl<GoodsSizeMapper, GoodsSizeEntity> implements IGoodsSizeService {

    @Resource
    private IGoodsService goodsService;

    @Resource
    private ICustomerCartService customerCartService;

    @Resource
    private ICustomerService customerService;


    /**
     * 查询商品规格列表
     *
     * @return
     * @throws Exception
     */
    @Override
    public List<GoodsSizeResponse> goodsSizeResponseList(GoodsSizeListRequest request) {
        List<GoodsSizeEntity> list = list(new LambdaQueryWrapper<GoodsSizeEntity>()
                .eq(null != request.getGoodsId(), GoodsSizeEntity::getGoodsId, request.getGoodsId())
                .like(StringUtils.hasText(request.getUnit()), GoodsSizeEntity::getUnit, request.getUnit()));
        return getResponse(list);
    }

    @Override
    public List<GoodsSizeResponse> goodsSizeResponseList(Long goodsId) {
        GoodsSizeListRequest request = new GoodsSizeListRequest();
        request.setGoodsId(goodsId);
        return goodsSizeResponseList(request);
    }

    @Override
    public List<GoodsSizeResponse> listResponseByIds(List<Long> ids) {
        List<GoodsSizeEntity> goodsSizeEntities = listByIds(ids);
        return getResponse(goodsSizeEntities);
    }

    private List<GoodsSizeResponse> getResponse(List<GoodsSizeEntity> goodsSizeEntities) {
        List<GoodsSizeResponse> ret = new ArrayList<>();
        if (!CollectionUtils.isEmpty(goodsSizeEntities)) {
            Set<Long> goodsIds = goodsSizeEntities.stream().map(GoodsSizeEntity::getGoodsId).collect(Collectors.toSet());
            List<GoodsEntity> goodsEntities = goodsService.listByIds(goodsIds);
            Map<Long, GoodsEntity> collect = goodsEntities.stream().collect(Collectors.toMap(GoodsEntity::getId, Function.identity()));

            for (GoodsSizeEntity goodsSizeEntity : goodsSizeEntities) {
                GoodsSizeResponse rs = EntityUtils.entity2Response(GoodsSizeResponse.class, goodsSizeEntity);
                GoodsEntity goodsEntity = collect.getOrDefault(goodsSizeEntity.getGoodsId(), new GoodsEntity());
                if (null != goodsEntity) {
                    rs.setName(goodsEntity.getName());
                    rs.setGoods(EntityUtils.entity2Response(GoodsResponse.class, goodsEntity));
                }
                ret.add(rs);
            }
        }
        return ret;
    }

    @Override
    public List<GoodsSizeResponse> listByName(String name) {
        List<GoodsSizeEntity> list = list(new LambdaQueryWrapper<GoodsSizeEntity>().like(GoodsSizeEntity::getUnit, name));
        return getResponse(list);
    }

    @Override
    public List<CustomerCartResponse> customerAdd2CartList(Serializable customerId) {
        List<CustomerCart> list = customerCartService.list(new LambdaQueryWrapper<CustomerCart>().eq(CustomerCart::getCustomerId, customerId));
        if(!CollectionUtils.isEmpty(list)) {
            List<CustomerCartResponse> ret = new ArrayList<>();
            Map<Long, CustomerCart> goodsSizeId2CustomerCart = list.stream().collect(Collectors.toMap(CustomerCart::getGoodsSizeId, Function.identity(), (e1, e2) -> e1));
            List<Long> collect = list.stream().map(CustomerCart::getGoodsSizeId).collect(Collectors.toList());
            List<GoodsSizeResponse> goodsSizeResponses = listResponseByIds(collect);
            for (GoodsSizeResponse goodsSizeResponse : goodsSizeResponses) {
                final CustomerCart customerCart = goodsSizeId2CustomerCart.getOrDefault(goodsSizeResponse.getId(), new CustomerCart());
                final CustomerCartResponse customerCartResponse = getCustomerCartResponse(goodsSizeResponse, customerCart);
                ret.add(customerCartResponse);
            }
            return ret;
        }
        return List.of();
    }

    private static @NotNull CustomerCartResponse getCustomerCartResponse(GoodsSizeResponse goodsSizeResponse, CustomerCart customerCart) {
        CustomerCartResponse customerCartResponse = new CustomerCartResponse();
        customerCartResponse.setId(customerCart.getId());
        customerCartResponse.setGoodsSize(goodsSizeResponse);
        customerCartResponse.setBuyNumber(customerCart.getBuyNumber());
        customerCartResponse.setUnitPrice(goodsSizeResponse.getUnitPrice());
        customerCartResponse.setTotalPrice(goodsSizeResponse.getUnitPrice().multiply(new BigDecimal(customerCartResponse.getBuyNumber())));
        return customerCartResponse;
    }

    @Override
    public boolean add2Cart(CustomerCart request) {
        boolean ret = false;
        CustomerEntity customer = customerService.getById(request.getCustomerId());
        if(null != customer) {
            request.setMerId(customer.getMerId());
            request.setShopId(customer.getShopId());
            CustomerCart one = customerCartService.getOne(new LambdaQueryWrapper<CustomerCart>()
                    .eq(CustomerCart::getCustomerId, request.getCustomerId())
                    .eq(CustomerCart::getGoodsSizeId, request.getGoodsSizeId())
                    , false);
            if(null != one) {
                one.setBuyNumber(one.getBuyNumber() + 1);
                ret = customerCartService.updateById(one);
            }else {
                ret = customerCartService.save( request);
            }
        }
        return ret;
    }

    @Override
    public boolean updateCart(CustomerCart request) {
        boolean ret = false;
        if(null == request.getId()) {
            return ret;
        }
        final List<CustomerCartResponse> customerCartResponses = customerAdd2CartList(request.getCustomerId());
        for (CustomerCartResponse customerCart : customerCartResponses) {
            if(customerCart.getGoodsSize().getId().equals(request.getGoodsSizeId())){
                if(request.getBuyNumber() <= 0) {
                    ret = customerCartService.removeFromCart(customerCart.getId());
                }else {
                    ret = customerCartService.updateBuyNumber(customerCart.getId(),request.getBuyNumber());
                }
            }
        }
        return ret;
    }

    @Override
    public Long addSize(GoodsSizeAddRequest request) {
        EntityUtils.setCreator(request,request.getOperator());
        return EntityUtils.addEntity(getBaseMapper(),GoodsSizeEntity.class,request);
    }

    @Override
    public boolean onSellSwitch(GoodsSizeEntity request) {
        boolean ret = false;
        if (null != request.getIsOnSell() && null != request.getId()) {
            ret = update(new LambdaUpdateWrapper<GoodsSizeEntity>().set(GoodsSizeEntity::getIsOnSell, request.getIsOnSell()).eq(GoodsSizeEntity::getId, request.getId()));
        }
        return ret;
    }
}
